package malagaAcoge.controller.beans;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.StringTokenizer;

import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.servlet.http.HttpServletResponse;

import malagaAcoge.controller.daos.DemandaDao;
import malagaAcoge.controller.daos.DepartamentoDao;
import malagaAcoge.controller.daos.DocumentoDao;
import malagaAcoge.model.entities.Demanda;
import malagaAcoge.model.entities.Departamento;
import malagaAcoge.model.entities.Documento;
import malagaAcoge.model.entities.Tecnico;
import malagaAcoge.model.entities.Usuario;
import malagaAcoge.utils.Messages;

import org.primefaces.event.FileUploadEvent;
import org.primefaces.event.RowEditEvent;

public class DemandasBean {
	private Usuario usuarioSelecionado;
	private Tecnico currentTecnico;
	private Demanda demanda;
	private List<Demanda> demandasUsuarioSeleccionado;
	private Demanda demandaSeleccionada;
	private HashMap<String, byte[]> documentos;
	private List<String> nombresDocumentos;
	private String documento;
	private String path;
	private List<Demanda> demandasDeDepartamentos;
	private Documento documentoAEliminar;
	private Demanda demandaAmodificar;
	private SimpleDateFormat sdf = new SimpleDateFormat(
			Messages.getString("DemandasBean.formatoFecha"));
	private String cadenaUsuario;
	private String departamento;
	private String cadenaTecnico;
	private HashMap<String, String> nombreDepartamentos;

	public DemandasBean() {
		setCurrentTecnico((Tecnico) FacesContext.getCurrentInstance()
				.getExternalContext().getSessionMap().get("tecnico")); //$NON-NLS-1$
		if (getUsuarioSelecionado() == null) {
			demanda = new Demanda();
		}
		demanda = new Demanda();
		if (getDocumentos() == null) {
			documentos = new HashMap<String, byte[]>();
			FacesContext.getCurrentInstance().getExternalContext()
					.getSessionMap().put("documentos", documentos);
		}
	}

	public void handleFileUpload(FileUploadEvent event) {
		getDocumentos();
		documentos.put(event.getFile().getFileName(), event.getFile()
				.getContents());
		FacesContext.getCurrentInstance().getExternalContext().getSessionMap()
				.put("documentos", documentos); //$NON-NLS-1$
		FacesMessage msg = new FacesMessage("Exito", event.getFile() //$NON-NLS-1$
				.getFileName() + " subido con exito."); //$NON-NLS-1$
		FacesContext.getCurrentInstance().addMessage(null, msg);
	}

	private boolean guardarArchivo(byte[] archivo, String nombre, int idDemanda) {
		boolean ok = false;
		try {
			File file = new File(
					Messages.getString("DemandasBean.directorio") + idDemanda); //$NON-NLS-1$
			if (!file.exists()) {
				file.mkdir();
			}
			file = new File(
					Messages.getString("DemandasBean.directorio") + idDemanda + "\\" + nombre); //$NON-NLS-1$ //$NON-NLS-2$
			FileOutputStream fos = new FileOutputStream(file);
			fos.write(archivo);
			fos.flush();
			fos.close();
			ok = true;
		} catch (Exception e) {
			System.out.println("Problema al guardar el fichero: " + nombre); //$NON-NLS-1$
		}
		return ok;
	}
	public void addDemanda() {
		new DemandaDao();
		demanda.setUsuarioBean(usuarioSelecionado);
		demanda.setTecnicoBean(currentTecnico);
		demanda.setFechaCreacion(sdf.format(new Date()));
		demanda.setEstado(Messages.getString("DemandasBean.activa")); //$NON-NLS-1$
		DemandaDao.createDemanda(demanda);
		if (getDocumentos() != null) {
			List<Documento> documentosList = new ArrayList<Documento>();
			for (String nombre : documentos.keySet()) {
				Documento documento = new Documento();
				documento.setTipo(nombre);
				documento.setFecha(sdf.format(new Date()));
				documento.setDemandaBean(demanda);
				if (guardarArchivo(documentos.get(nombre), nombre,
						demanda.getIdDemanda())) {
					new DocumentoDao();
					DocumentoDao.createDocumento(documento);
					documentosList.add(documento);
				}
			}
			demanda.setDocumentos(documentosList);
			new DemandaDao();
			DemandaDao.mergeDemanda(demanda);
		}
		if (usuarioSelecionado.getDemandas() == null) {
			usuarioSelecionado.setDemandas(new ArrayList<Demanda>());
		}
		usuarioSelecionado.getDemandas().add(demanda);
		FacesContext.getCurrentInstance().getExternalContext().getSessionMap()
				.put("usuario", usuarioSelecionado); //$NON-NLS-1$
		FacesContext context = FacesContext.getCurrentInstance();
		context.addMessage(null, new FacesMessage("Exito", //$NON-NLS-1$
				"Demanda registrada correctamente.")); //$NON-NLS-1$
		demanda = new Demanda();
		FacesContext.getCurrentInstance().getExternalContext().getSessionMap()
				.put("documentos", new HashMap<String, byte[]>());
		demandasDeDepartamentos = null;
		demandasUsuarioSeleccionado = null;
	}

	public void updateDemanda(RowEditEvent event) {
		Demanda d = (Demanda) event.getObject();
		d.setFechaModificacion(sdf.format(new Date())
				+ " [" + getCurrentTecnico().getNombre() + " " + getCurrentTecnico().getApellidos() + "]"); //$NON-NLS-1$
		new DemandaDao();
		DemandaDao.mergeDemanda(d);
		if (getUsuarioSelecionado() != null
				&& d.getUsuarioBean().equals(usuarioSelecionado)) {
			int i = usuarioSelecionado.getDemandas().indexOf(d);
			usuarioSelecionado.getDemandas().set(i, d);
			FacesContext.getCurrentInstance().getExternalContext()
					.getSessionMap().put("usuario", usuarioSelecionado);
		}
		demandasDeDepartamentos = null;
		demandasUsuarioSeleccionado = null;
	}

	public void guardarDocumentos() {
		demandaAmodificar = (Demanda) FacesContext.getCurrentInstance()
				.getExternalContext().getSessionMap()
				.remove("demandaAmodificar");
		new DocumentoDao();
		if (getDocumentos() != null) {
			List<Documento> documentosList = new ArrayList<Documento>();
			for (String nombre : documentos.keySet()) {
				Documento documento = new Documento();
				documento.setTipo(nombre);
				documento.setFecha(sdf.format(new Date()));
				documento.setDemandaBean(demandaAmodificar);
				if (guardarArchivo(documentos.get(nombre), nombre,
						demandaAmodificar.getIdDemanda())) {
					new DocumentoDao();
					DocumentoDao.createDocumento(documento);
					documentosList.add(documento);
				}
			}
			if (demandaAmodificar.getDocumentos() == null) {
				demandaAmodificar.setDocumentos(new ArrayList<Documento>());
			}
			demandaAmodificar.getDocumentos().addAll(documentosList);
			demandaAmodificar.setFechaModificacion(sdf.format(new Date())
					+ " [" + getCurrentTecnico().getNombre() + " "
					+ getCurrentTecnico().getApellidos() + "]");
			new DemandaDao();
			DemandaDao.mergeDemanda(demandaAmodificar);
		}
		demandasDeDepartamentos = null;
		demandasUsuarioSeleccionado = null;
		FacesContext.getCurrentInstance().getExternalContext().getSessionMap()
				.put("documentos", new HashMap<String, byte[]>());
	}

	public void eliminarDocumento() {
		documentoAEliminar = (Documento) FacesContext.getCurrentInstance()
				.getExternalContext().getSessionMap()
				.remove("documentoAEliminar");
		Demanda d = documentoAEliminar.getDemandaBean();
		new DocumentoDao();
		DocumentoDao.deleteDocumento(documentoAEliminar.getIdDocumento());
		new DemandaDao();
		d.getDocumentos().remove(documentoAEliminar);
		d.setFechaModificacion(sdf.format(new Date()) + " ["
				+ getCurrentTecnico().getNombre() + " "
				+ getCurrentTecnico().getApellidos() + "]");
		DemandaDao.mergeDemanda(d);
		FacesContext context = FacesContext.getCurrentInstance();
		context.addMessage(null,
				new FacesMessage("Exito", "Documento borrado."));
		demandasUsuarioSeleccionado = null;
		demandasDeDepartamentos = null;
	}

	public void setUsuarioSelecionado(Usuario usuarioSelecionado) {

		this.usuarioSelecionado = usuarioSelecionado;
	}

	public Usuario getUsuarioSelecionado() {
		usuarioSelecionado = (Usuario) FacesContext.getCurrentInstance()
				.getExternalContext().getSessionMap().get("usuario"); //$NON-NLS-1$
		return usuarioSelecionado;
	}

	public void setCurrentTecnico(Tecnico currentTecnico) {
		this.currentTecnico = currentTecnico;
	}

	public Tecnico getCurrentTecnico() {
		return currentTecnico;
	}

	public void setDemanda(Demanda demanda) {
		this.demanda = demanda;
	}

	public Demanda getDemanda() {
		return demanda;
	}

	public void setDemandasUsuarioSeleccionado(
			List<Demanda> demandasUsuarioSeleccionado) {
		this.demandasUsuarioSeleccionado = demandasUsuarioSeleccionado;
	}

	public List<Demanda> getDemandasUsuarioSeleccionado() {
		if (demandasUsuarioSeleccionado == null
				&& getUsuarioSelecionado() != null) {
			new DemandaDao();
			if (getCurrentTecnico().getDepartamentoBean().getNombre()
					.equals("Administracion")
					|| getCurrentTecnico().getDepartamentoBean().getNombre()
							.equals("Direccion")) {
				demandasUsuarioSeleccionado = DemandaDao
						.findDemandasDeUsuario(usuarioSelecionado
								.getIdUsuario());

			} else {
				demandasUsuarioSeleccionado = DemandaDao.findDemandasDeUsuario(
						getCurrentTecnico().getDepartamentoBean()
								.getIdDepartamento(), usuarioSelecionado
								.getIdUsuario());
			}
		}
		return demandasUsuarioSeleccionado;
	}

	public void setDemandaSeleccionada(Demanda demandaSeleccionada) {
		this.demandaSeleccionada = demandaSeleccionada;
		FacesContext.getCurrentInstance().getExternalContext().getSessionMap()
				.put("demandaSeleccionada", demandaSeleccionada);
	}

	public Demanda getDemandaSeleccionada() {
		demandaSeleccionada= (Demanda) FacesContext.getCurrentInstance().getExternalContext().getSessionMap()
		.get("demandaSeleccionada");
		return demandaSeleccionada;
	}

	public void setDocumentos(HashMap<String, byte[]> documentos) {
		this.documentos = documentos;
	}

	@SuppressWarnings("unchecked")
	public HashMap<String, byte[]> getDocumentos() {
		documentos = (HashMap<String, byte[]>) FacesContext
				.getCurrentInstance().getExternalContext().getSessionMap()
				.get("documentos"); //$NON-NLS-1$
		return documentos;
	}

	public void setNombresDocumentos(List<String> nombresDocumentos) {
		this.nombresDocumentos = nombresDocumentos;
	}

	public List<String> getNombresDocumentos() {
		nombresDocumentos = new ArrayList<String>();
		nombresDocumentos.addAll(getDocumentos().keySet());
		return nombresDocumentos;
	}

	@SuppressWarnings("unchecked")
	public void quitarDocumento() {
		documentos = (HashMap<String, byte[]>) FacesContext
				.getCurrentInstance().getExternalContext().getSessionMap()
				.get("documentos");
		documentos.remove(documento);
		FacesContext.getCurrentInstance().getExternalContext().getSessionMap()
				.put("documentos", documentos);

	}

	public void setDocumento(String documento) {
		this.documento = documento;
	}

	public String getDocumento() {
		return documento;
	}

	public void setPath(String path) {
		this.path = path;
	}

	public void descargarArchivo() {
		String ruta = Messages.getString("DemandasBean.directorio");
		StringTokenizer tokenizer = new StringTokenizer(path, ",");
		String idDemanda = tokenizer.nextToken();
		String nombre = tokenizer.nextToken();
		ruta += idDemanda + "\\" + nombre;
		File file = new File(ruta);
		if (file.exists()) {
			try {
				FacesContext facesContext = FacesContext.getCurrentInstance();
				HttpServletResponse response = (HttpServletResponse) facesContext
						.getExternalContext().getResponse();
				String contentDispositionValue = "attachment";
				if (nombre.contains(".doc") || nombre.contains(".docx")) {
					response.setContentType("application/msword");
				} else {
					response.setContentType("application/octet-strem");
				}
				response.setHeader("Content-Disposition",
						contentDispositionValue + ";filename=\"" + nombre
								+ "\"");
				byte[] buffer = new byte[2048];
				int length;
				InputStream inputStream = new FileInputStream(file);
				OutputStream outputStream = response.getOutputStream();

				while ((length = (inputStream.read(buffer))) != -1) {
					outputStream.write(buffer, 0, length);
				}

				response.setStatus(200);

				response.getOutputStream().flush();
				inputStream.close();
				facesContext.responseComplete();
			} catch (IOException e) {
				System.out.println("Error al descargar el archivo: " + ruta);
			}
		}
	}

	public String getPath() {
		return path;
	}

	public void setDemandasDeDepartamentos(List<Demanda> demandasDeDepartamentos) {
		this.demandasDeDepartamentos = demandasDeDepartamentos;
	}

	public List<Demanda> getDemandasDeDepartamentos() {
		if (demandasDeDepartamentos == null) {
			new DemandaDao();
			if (getCurrentTecnico().getDepartamentoBean().getNombre()
					.equals("Administracion")
					|| getCurrentTecnico().getDepartamentoBean().getNombre()
							.equals("Direccion")) {
				demandasDeDepartamentos = DemandaDao.findAll();

			} else {
				demandasDeDepartamentos = DemandaDao
						.findDemandasDeDepartamento(getCurrentTecnico()
								.getDepartamentoBean().getIdDepartamento());
			}
		}
		return demandasDeDepartamentos;
	}

	public void setDocumentoAEliminar(Documento documentoAEliminar) {
		this.documentoAEliminar = documentoAEliminar;
		FacesContext.getCurrentInstance().getExternalContext().getSessionMap()
				.put("documentoAEliminar", documentoAEliminar);
	}

	public Documento getDocumentoAEliminar() {
		return documentoAEliminar;
	}

	public void setDemandaAmodificar(Demanda demandaAmodificar) {
		this.demandaAmodificar = demandaAmodificar;
		FacesContext.getCurrentInstance().getExternalContext().getSessionMap()
				.put("demandaAmodificar", demandaAmodificar);
	}

	public Demanda getDemandaAmodificar() {
		return demandaAmodificar;
	}

	public void setCadenaUsuario(String cadenaUsuario) {
		this.cadenaUsuario = cadenaUsuario;
	}

	public String getCadenaUsuario() {
		return cadenaUsuario;
	}

	public HashMap<String, String> getNombreDepartamentos() {
		nombreDepartamentos = new HashMap<String, String>();
		new DepartamentoDao();
		List<Departamento> departamentos = DepartamentoDao.findAll();
		for (Departamento dep : departamentos) {
			nombreDepartamentos.put(dep.getNombre(),
					String.valueOf(dep.getIdDepartamento()));
		}
		return nombreDepartamentos;
	}

	public void setCadenaTecnico(String cadenaTecnico) {
		this.cadenaTecnico = cadenaTecnico;
	}

	public String getCadenaTecnico() {
		return cadenaTecnico;
	}

	public void setDepartamento(String departamento) {
		this.departamento = departamento;
	}

	public String getDepartamento() {
		return departamento;
	}

	public void limpiar() {
		cadenaUsuario = "";
		cadenaTecnico = "";
		departamento = "";
		demandasDeDepartamentos = null;
	}

	public void buscar() {
		new DemandaDao();
		int idDep = 0;
		if (cadenaUsuario == null) {
			cadenaUsuario = "";
		}
		if (cadenaTecnico == null) {
			cadenaTecnico = "";
		}
		if (departamento != null && !departamento.equals("")) {
			idDep = Integer.parseInt(departamento);
		}
		List<Demanda> aux = getDemandasDeDepartamentos();
		demandasDeDepartamentos = new ArrayList<Demanda>();
		for (Demanda demanda : aux) {
			String usuario = (demanda.getUsuarioBean().getNombre() + " " + demanda
					.getUsuarioBean().getApellidos()).toUpperCase();
			String tecnico = (demanda.getTecnicoBean().getNombre() + " " + demanda
					.getTecnicoBean().getApellidos()).toUpperCase();
			if (idDep == 0) {
				if (usuario.contains(cadenaUsuario.toUpperCase())
						&& tecnico.toUpperCase().contains(
								cadenaTecnico.toUpperCase())) {
					demandasDeDepartamentos.add(demanda);
				}
			} else {
				int id = demanda.getTecnicoBean().getDepartamentoBean()
						.getIdDepartamento();
				if (usuario.contains(cadenaUsuario.toUpperCase())
						&& tecnico.contains(cadenaTecnico.toUpperCase())
						&& idDep == id) {
					demandasDeDepartamentos.add(demanda);
				}
			}
		}
	}
}
